﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Jb.Common.Extensions;
using Jb.Domain;
using Jb.Search;

namespace Jb.Web.Utility
{
    public static class JbEvents
    {
        #region Resume Events

        /// <summary>
        /// Fires when a resume is deleted 
        /// </summary>
        /// <param name="resume"></param>
        /// <param name="context"></param>
        public static void ResumeDeleted(Resume resume, JbEntities context = null)
        {
            //SessionCache.CurrentUser.JobSeekerInfo.TotalResumes -= 1;
            SessionCache.RefreshUserInfo();
        }

        /// <summary>
        /// Fires when a resume is added
        /// </summary>
        /// <param name="resume"></param>
        /// <param name="context"></param>
        public static void ResumeAdded(Resume resume, JbEntities context = null)
        {
            //SessionCache.CurrentUser.JobSeekerInfo.TotalResumes += 1;
            SessionCache.RefreshUserInfo();
        }

        #endregion

        #region Job Events

        /// <summary>
        /// Fires when a job is added to the System
        /// </summary>
        /// <param name="job"></param>
        /// <param name="context"></param>
        public static void JobAdded(Job job, JbEntities context = null)
        {
            //SessionCache.CurrentUser.EmployerInfo.TotalJobs += 1;
            if (job.IsActive)
                JobActivated(job, context);
            //else            
            //    SessionCache.CurrentUser.EmployerInfo.TotalUnPublishedJobs += 1;

            ///Add subscription History
            if (context != null)
            {
                SubscriptionHistory history = new SubscriptionHistory();
                history.CompanyID = job.CompanyID;
                history.PackageID = SessionCache.CurrentUser.EmployerInfo.Subscription.PackageID;
                history.JobID = job.ID;
                history.CreatedOn = DateTime.Now;
                context.AddToSubscriptionHistories(history);
                context.SaveChanges();
            }

            SessionCache.RefreshUserInfo();
        }

        /// <summary>
        /// Fires When a Job is Updated. Readjusts the Employer Total Active Job Count, Total Unpublished Job Count
        /// </summary>
        /// <param name="job"></param>
        /// <param name="context"></param>
        public static void JobUpdated(Job job, bool oldValueOfIsActive, JbEntities context = null)
        {
            if (job.IsActive != oldValueOfIsActive) ///Means Activation state has changed
            {
                if (job.IsActive)
                    JobActivated(job, context);
                else
                    JobDeActivated(job, context);
            }
            //else
            //    JobActivated(job, context);

            SessionCache.RefreshUserInfo();
        }

        /// <summary>
        /// Fires when a Job is Deleted
        /// </summary>
        /// <param name="job"></param>
        /// <param name="context"></param>
        public static void JobDeleted(Job job, JbEntities context = null)
        {
            //SessionCache.CurrentUser.EmployerInfo.TotalJobs -= 1;
            if (job.IsActive)
                JobDeActivated(job, context);
            SessionCache.RefreshUserInfo();
        }

        /// <summary>
        /// Fires when a job is Activated
        /// </summary>
        /// <param name="job"></param>
        /// <param name="context"></param>
        public static void JobActivated(Job job, JbEntities context = null)
        {            
            ///Index Newly Added Document
            IIndexer jobIndexer = IndexerFactory.GetIndexer(job.GetType());
            jobIndexer.UpdateIndex<Job>(job, "Jb.Web.JobActivated");
            jobIndexer.CommitChanges();
            jobIndexer.CloseWriter();
            ///Reload Job Searcher
            ISearcher jobSearcher = SearcherFactory.GetSearcher(job.GetType());
            jobSearcher.Reload();

            UpdateActiveJobCount(1, job, context);
        }

        /// <summary>
        /// Fires when a Job is Deactivated
        /// </summary>
        /// <param name="job"></param>
        /// <param name="context"></param>
        public static void JobDeActivated(Job job, JbEntities context = null)
        {
            //SessionCache.CurrentUser.EmployerInfo.TotalActiveJobs -= 1;
            //SessionCache.CurrentUser.EmployerInfo.TotalUnPublishedJobs += 1;
            ///Remove Index of Current Document
            IIndexer jobIndexer = IndexerFactory.GetIndexer(job.GetType());
            jobIndexer.DeleteIndex(job.ID);
            jobIndexer.CommitChanges();
            jobIndexer.CloseWriter();
            ///Reload Job Searcher
            ISearcher jobSearcher = SearcherFactory.GetSearcher(job.GetType());
            jobSearcher.Reload();

            UpdateActiveJobCount(-1, job, context);
        }
        #endregion

        #region Category Events

        /// <summary>
        /// Fires when a new category is added
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="_Context"></param>
        public static void CategoryAdded(Category entity, JbEntities _Context)
        {
            ApplicationCache.RefreshCategoryCache();
        }

        /// <summary>
        /// Fires when an existing category is updated
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="oldCategoryName"></param>
        /// <param name="_Context"></param>
        public static void CategoryUpdated(Category entity, string oldCategoryName, JbEntities _Context)
        {
            ApplicationCache.RefreshCategoryCache();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Increases or Decreases Job Count by given increaseCount to the child category and parent category also.
        /// A negative increaseCountBy will decrease the Active Job Count
        /// </summary>
        /// <param name="increaseCountBy">Should be +1 or -1 for a Single job update operation</param>
        /// <param name="job"></param>
        /// <param name="context"></param>
        private static void UpdateActiveJobCount(int increaseCountBy, Job job, JbEntities context)
        {
            if (context == null)
                context = new JbEntities();
            Category category = context.Categories.FirstOrDefault(P => P.ID == job.CategoryID);
            category.ActiveJobCount += increaseCountBy;
            ///Update the parent category if it exists
            if (category.ParentCategory != null)
            {
                category.ParentCategory.ActiveJobCount += increaseCountBy;
            }
            context.SaveChanges();
            ApplicationCache.RefreshCategoryCache();
        }

        #endregion Private Methods
        
    }
}